package com.anasoft.os.m2st.doxia.macro;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.commons.io.IOUtils;

/**
 * Parametrized HTML snippet consisting of HTML template
 * and specific parameter values, both denoted by {@link URL}s.
 * 
 * <p>
 * 
 * Each HTML snippet represents either a continuous data region
 * taken from the HTML template (<tt>id</tt> is not <tt>null</tt>)
 * or the entire HTML template (<tt>id</tt> is <tt>null</tt>).
 * See {@link BaseMacro#loadSnippet(String, URL, String)} for information
 * about using snippet <tt>id</tt> within your source files.
 * 
 * <p>
 * 
 * Note that parameter values content should conform to Java
 * {@link Properties} file format.
 * 
 * @see HtmlTemplateSnippetMacro
 * 
 * @author vojtech.szocs
 */
public class HtmlTemplateSnippet {

    private final String template;
    private final Properties paramValues;
    private final boolean missingValuesToEmptyStrings;
    
    /**
     * Creates a new HTML snippet.
     * 
     * @param id HTML template snippet identifier (can be <tt>null</tt>
     * to include the entire HTML template contents).
     * @param templateUrl HTML template {@link URL}.
     * @param paramValuesUrl Parameter values {@link URL}.
     * @param encoding Source file encoding.
     * @param missingValuesToEmptyStrings If set to <tt>true</tt>,
     * missing parameter values will be replaced with empty strings
     * in the final HTML code.
     * @throws IOException
     */
    public HtmlTemplateSnippet(String id, URL templateUrl, URL paramValuesUrl, String encoding, boolean missingValuesToEmptyStrings) throws IOException {
        this.missingValuesToEmptyStrings = missingValuesToEmptyStrings;
        
        template = BaseMacro.loadSnippet(id, templateUrl, encoding);
        
        InputStream paramValuesIn = paramValuesUrl.openStream();
        
        try {
            paramValues = new Properties();
            paramValues.load(paramValuesIn);
        } finally {
            IOUtils.closeQuietly(paramValuesIn);
        }
    }
    
    /**
     * Replaces parameters with corresponding values
     * within the HTML template and returns the resulting
     * HTML code.
     * 
     * @return Snippet HTML code.
     */
    @SuppressWarnings("unchecked")
    @Override
    public String toString() {
        Enumeration<String> paramNames = (Enumeration<String>) paramValues.propertyNames();
        String result = template;
        
        while (paramNames.hasMoreElements()) {
            String param = paramNames.nextElement();
            result = result.replaceAll("\\$\\{" + param + "\\}", paramValues.getProperty(param));
        }
        
        if (missingValuesToEmptyStrings) {
            result = result.replaceAll("\\$\\{.*\\}", "");
        }
        
        return result;
    }
    
}
